﻿using Common;
using Common.Helper;
using IService.Blog;
using IService.Common;
using IService.Entity;
using log4net;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Model;
using SqlSugar.Extensions;
using StackExchange.Profiling;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Service.Common
{
    public class LoginServices: ILoginServices
    {
        //数据仓储接口
        readonly ILog log = LogManager.GetLogger(typeof(LoginServices));
        readonly IBUserService bUserService;
        readonly IHomeService homeService;
        /// <summary>
        /// 构造函数注入
        /// </summary>
        /// <param name="_bsUserServices"></param>
        /// <param name="requirement"></param>
        /// <param name="_bsRolePermissionServices"></param>
        public LoginServices(IBUserService _bUserService, IHomeService _homeService)
        {
            this.bUserService = _bUserService;
            homeService = _homeService;
        }

        /// <summary>
        /// 用户登录接口：获取Token值
        /// </summary>
        /// <param name="name">用户名</param>
        /// <param name="pass">密码</param>
        /// <param name="code">验证码</param>
        /// <returns></returns>
        [Caching(AbsoluteExpiration = 1)]
        [UseTran]
        public async Task<MessageModel<TokenInfoModel>> UserLogin(string name = "", string pass = "", string code="")
        {
            try
            {
                BUser bUser;
                //通过账户获取用户信息，code 应是唯一性，新增用户需要考虑这点
                using (MiniProfiler.Current.Step("通过账户获取用户信息："))
                {
                    bUser = (await bUserService.GetByExpression<BUser>((System.Linq.Expressions.Expression<Func<BUser, bool>>)(t => t.UserName == name))).Data.FirstOrDefault();
                }

                if (bUser == null)
                {
                    return new MessageModel<TokenInfoModel>()
                    {
                        Success = false,
                        Message = "账号错误",
                    };
                }
                else
                {
                    //获取用户密码 比对输入的密码
                    if (!MD5Helper.MD5Decrypt(pass, bUser.Password))
                    {
                        return new MessageModel<TokenInfoModel>()
                        {
                            Success = false,
                            Message = "密码错误",
                        };
                    }
                    else
                    {
                        if (!homeService.Validate(AppSettings.read("VCID"), code).Result.Data)
                        {
                            return new MessageModel<TokenInfoModel>()
                            {
                                Success = false,
                                Message = "验证码错误",
                            };
                        }
                        //如果是基于用户的授权策略，这里要添加用户;如果是基于角色的授权策略，这里要添加角色
                        var claims = new List<Claim> {
                        new Claim(ClaimTypes.Name, bUser.UserName),
                        new Claim(JwtRegisteredClaimNames.Jti, bUser.ID.ToString()),
                        new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(new TimeSpan().TotalSeconds).ToString()) };
                        claims.AddRange(bUser.UserName.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));

                        //用户标识
                        var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
                        identity.AddClaims(claims);

                        var token = JwtToken.BuildJwtToken(claims.ToArray());
                        token.User = bUser;
                        return new MessageModel<TokenInfoModel>()
                        {
                            Success = true,
                            Message = "获取成功",
                            Data = token,
                        };

                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("服务异常" + ex.Message);
                return new MessageModel<TokenInfoModel>()
                {
                    Success = false,
                    Message = "服务异常:" + ex.Message
                };
            }

        }


        /// <summary>
        /// 请求刷新Token（以旧换新）
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task<MessageModel<TokenInfoModel>> GetUserTokenRefresh(string token = "")
        {
            try
            {
                string jwtStr = string.Empty;

                if (string.IsNullOrEmpty(token))
                {
                    return new MessageModel<TokenInfoModel>()
                    {
                        Success = false,
                        Message = "token无效，请重新登录！",
                    };
                }
                var tokenModel = JwtHelper.JWTDecode(token);
                if (tokenModel != null && tokenModel.Uid > 0)
                {
                    var user = await bUserService.GetById((int)tokenModel.Uid);
                    if (user != null)
                    {
                        //如果是基于用户的授权策略，这里要添加用户;如果是基于角色的授权策略，这里要添加角色
                        var claims = new List<Claim> {
                        new Claim(ClaimTypes.Name, user.Data.UserName),
                        new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()),
                        new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(new TimeSpan().TotalSeconds).ToString()) };
                        claims.AddRange(user.Data.UserName.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));

                        //用户标识
                        var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
                        identity.AddClaims(claims);

                        var refreshToken = JwtToken.BuildJwtToken(claims.ToArray());
                        return new MessageModel<TokenInfoModel>()
                        {
                            Success = true,
                            Message = "获取成功",
                            Data = refreshToken
                        };
                    }
                }

                return new MessageModel<TokenInfoModel>()
                {
                    Success = false,
                    Message = "认证失败！",
                };
            }
            catch (Exception ex)
            {
                log.Error("服务异常" + ex.Message);
                return new MessageModel<TokenInfoModel>()
                {
                    Success = false,
                    Message = "服务异常:" + ex.Message
                };
            }

        }
    }
}
